libobs_wrapper\data\traits/
getters.rs1use std::ffi::CStr;
2
3use crate::{
4 data::ObsDataPointers,
5 run_with_obs,
6 unsafe_send::SmartPointerSendable,
7 utils::{ObsError, ObsString},
8};
9
10#[allow(unknown_lints)]
13#[allow(ensure_obs_call_in_runtime)]
14unsafe fn has_value(
15 data_ptr: SmartPointerSendable<*mut libobs::obs_data_t>,
16 key: &ObsString,
17) -> bool {
18 libobs::obs_data_has_user_value(data_ptr.get_ptr(), key.as_ptr().0)
19 || libobs::obs_data_has_default_value(data_ptr.get_ptr(), key.as_ptr().0)
20}
21
22#[allow(private_bounds)]
23pub trait ObsDataGetters: ObsDataPointers {
24 fn get_string<T: Into<ObsString> + Send + Sync>(
25 &self,
26 key: T,
27 ) -> Result<Option<String>, ObsError> {
28 let key = key.into();
29 let data_ptr = self.as_ptr();
30
31 run_with_obs!(self.runtime(), (data_ptr, key), move || {
32 let has_value = unsafe {
33 has_value(data_ptr.clone(), &key)
35 };
36
37 if has_value {
38 let result = unsafe {
39 libobs::obs_data_get_string(data_ptr.get_ptr(), key.as_ptr().0)
41 };
42
43 if result.is_null() {
44 Err(ObsError::NullPointer(None))
45 } else {
46 let result = unsafe {
47 CStr::from_ptr(result)
49 };
50 let result = result
51 .to_str()
52 .map_err(|_| ObsError::StringConversionError)?
53 .to_string();
54
55 Ok(Some(result))
56 }
57 } else {
58 Ok(None)
59 }
60 })?
61 }
62 fn get_int<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<i64>, ObsError> {
63 let key = key.into();
64 let data_ptr = self.as_ptr();
65
66 run_with_obs!(self.runtime(), (data_ptr, key), move || {
67 let has_value = unsafe {
68 has_value(data_ptr.clone(), &key)
70 };
71
72 if has_value {
73 Some(unsafe {
74 libobs::obs_data_get_int(data_ptr.get_ptr(), key.as_ptr().0)
76 })
77 } else {
78 None
79 }
80 })
81 }
82 fn get_bool<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<bool>, ObsError> {
83 let key = key.into();
84
85 let data_ptr = self.as_ptr();
86
87 run_with_obs!(self.runtime(), (data_ptr, key), move || {
88 let has_value = unsafe {
89 has_value(data_ptr.clone(), &key)
91 };
92
93 if has_value {
94 Some(unsafe {
95 libobs::obs_data_get_bool(data_ptr.get_ptr(), key.as_ptr().0)
97 })
98 } else {
99 None
100 }
101 })
102 }
103 fn get_double<T: Into<ObsString> + Sync + Send>(
104 &self,
105 key: T,
106 ) -> Result<Option<f64>, ObsError> {
107 let key = key.into();
108 let data_ptr = self.as_ptr();
109
110 let result = run_with_obs!(self.runtime(), (key, data_ptr), move || {
111 let has_value = unsafe {
112 has_value(data_ptr.clone(), &key)
114 };
115
116 if has_value {
117 Some(unsafe {
118 libobs::obs_data_get_double(data_ptr.get_ptr(), key.as_ptr().0)
120 })
121 } else {
122 None
123 }
124 })?;
125
126 Ok(result)
127 }
128
129 fn get_json(&self) -> Result<String, ObsError> {
130 let data_ptr = self.as_ptr();
131 run_with_obs!(self.runtime(), (data_ptr), move || {
132 let json_ptr = unsafe {
133 libobs::obs_data_get_json(data_ptr.get_ptr())
135 };
136
137 if json_ptr.is_null() {
138 return Err(ObsError::NullPointer(Some(
139 "Couldn't get json representation of OBS data".into(),
140 )));
141 }
142
143 let json = unsafe {
144 CStr::from_ptr(json_ptr)
146 }
147 .to_str()
148 .map_err(|_| ObsError::JsonParseError)?
149 .to_string();
150
151 Ok(json)
152 })?
153 }
154}